home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 4.iso / src / apps / ibrowse / ibrowse_sgi.c < prev    next >
C/C++ Source or Header  |  1994-08-01  |  8KB  |  268 lines

  1. /*
  2.  * Copyright 1993, 1994, Silicon Graphics, Inc.
  3.  * All Rights Reserved.
  4.  *
  5.  * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
  6.  * the contents of this file may not be disclosed to third parties, copied or
  7.  * duplicated in any form, in whole or in part, without the prior written
  8.  * permission of Silicon Graphics, Inc.
  9.  *
  10.  * RESTRICTED RIGHTS LEGEND:
  11.  * Use, duplication or disclosure by the Government is subject to restrictions
  12.  * as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
  13.  * and Computer Software clause at DFARS 252.227-7013, and/or in similar or
  14.  * successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
  15.  * rights reserved under the Copyright Laws of the United States.
  16.  */
  17. /*
  18.     ibrowse_sgi.c - Support for identifying and iconifying SGI format images.
  19.  
  20.     Tim Heidmann, Paul Haeberli, Silicon Graphics
  21.  
  22.     Version 1.2.2
  23.     November 29, 1993
  24.  
  25.     copyright 1993, Silicon Graphics
  26. */
  27.  
  28. #include <gl.h>
  29. #include <gl/image.h>
  30. #include <unistd.h>
  31. #include <stdlib.h>
  32. #include <stdio.h>
  33. #include <fcntl.h>
  34. #include <limits.h>
  35. #include <malloc.h>
  36. #include "ibrowse.h"
  37.  
  38. #define IPASTE_MARGIN 50
  39.  
  40. unsigned long *myColormap_SGI = NULL;
  41. void GetColormap_SGI();
  42.  
  43. int
  44. Check_SGI(struct iconDirStruct *ids, int fd) {
  45.     /* Check for SGI image type file.
  46.        If it is an image, set xsize, ysize, zsize.
  47.        Return TRUE iff it is an SGI format image file. */
  48.     int len;
  49.     IMAGE ibuf;
  50.  
  51.     len = read(fd, &ibuf, sizeof(ibuf));
  52.     if ((len == (signed int) sizeof(ibuf)) && (ibuf.imagic == IMAGIC)) {
  53.     ids->xsize   = ibuf.xsize;
  54.     ids->ysize   = ibuf.ysize;
  55.     ids->zsize   = ibuf.zsize;
  56.     ids->subType = ibuf.colormap << 16 | ibuf.type;
  57.     return TRUE;
  58.  
  59.     } else
  60.     return FALSE;
  61. }
  62.  
  63. /*
  64.  * Read image file and subsample into memory slot.
  65.  */
  66. #define PACK_RGBA_08(r, g, b, a) ((unsigned long) \
  67.     ((a)<<24 | (b)<<16 | (g)<<8 | (r)))
  68. #define PACK_RGBA_16(r, g, b, a) ((unsigned long) \
  69.     (((a)&0xff00)<<16 | ((b)&0xff00)<<8 | ((g)&0xff00) | ((r)&0xff00)>>8))
  70.  
  71. static short *rbuf = NULL, *gbuf, *bbuf, *abuf;
  72. static int rowlen = 0;
  73.  
  74. int
  75. Iconify_SGI(struct iconDirStruct *ids, unsigned long *ip) {
  76.     IMAGE *f;
  77.     short r, g, b;
  78.     char name_buf[PATH_MAX];
  79.     int irow, isrcrow, icol, startrow, endrow, startcol, endcol, isrccol;
  80.     int fileLen;
  81.     float srcrow, srccol, xsrcinc, ysrcinc;
  82.  
  83.     if (ids->xsize <= 0 || ids->ysize <= 0 || ids->zsize <= 0) return TRUE;
  84.  
  85.     /* Read sparse rows of the image to make an icon */
  86.     sprintf(name_buf, "%s/%s", theDirName, ids->name);
  87.     if ((f = iopen(name_buf, "r")) == NULL) return FALSE;
  88.  
  89.     /* Calculate sampling parameters */
  90.     xsrcinc = f->xsize / (float) ids->ixsize;
  91.     ysrcinc = f->ysize / (float) ids->iysize;
  92.  
  93.     /* Allocate row buffers */
  94.     if(f->xsize>rowlen) {
  95.     if(rbuf) {
  96.         free(rbuf);    
  97.         free(gbuf);    
  98.         free(bbuf);    
  99.         free(abuf);    
  100.     }
  101.     rowlen = f->xsize;
  102.     rbuf = (short *)malloc(rowlen*sizeof(short));
  103.     gbuf = (short *)malloc(rowlen*sizeof(short));
  104.     bbuf = (short *)malloc(rowlen*sizeof(short));
  105.     abuf = (short *)malloc(rowlen*sizeof(short));
  106.     }
  107.  
  108.     /* Point-sample the image */
  109.     for (irow = 0, srcrow = 0.5 * ysrcinc; irow < ids->iysize;
  110.         irow++, srcrow += ysrcinc) {
  111.     /* Read each component */
  112.     isrcrow = (int) srcrow;
  113.     getrow(f, rbuf, isrcrow, 0);
  114.     if (f->zsize >= 3) {
  115.         getrow(f, gbuf, isrcrow, 1);
  116.         getrow(f, bbuf, isrcrow, 2);
  117.         if (f->zsize > 3)
  118.         getrow(f, abuf, isrcrow, 3);
  119.     }
  120.  
  121.     /*
  122.      * Decode and pack components into ABGR word.
  123.      */
  124.     if (ids->subType>>16 == CM_SCREEN) {
  125.         /* Colormap image. Map the first channel with current map */
  126.         if (myColormap_SGI == NULL) GetColormap_SGI();
  127.         for (icol = 0, srccol = 0.5 * xsrcinc;
  128.             icol < ids->ixsize; icol++, srccol += xsrcinc, ip++) {
  129.         isrccol = (int) srccol;
  130.         /* Wrap indices > 255 around, so at least we see some detail */
  131.         *ip = myColormap_SGI[rbuf[isrccol] % 256] | 0xff000000;
  132.         }
  133.  
  134.     } else if ((ids->subType & BPPMASK) == 2) {
  135.         /* 2 bytes per pixel NORMAL image */
  136.         for (icol = 0, srccol = 0.5 * xsrcinc;
  137.             icol < ids->ixsize; icol++, srccol += xsrcinc, ip++) {
  138.         isrccol = (int) srccol;
  139. /* The following statements should probably use the PACK_RGBA_16 macro
  140.  * to convert 16-bit channels to 8-bit channels, but the SGI video products
  141.  * save 16-bit channels in the range 0-255, so use PACK_RGBA_08.
  142.  */
  143.         if (f->zsize > 3)
  144.             *ip = PACK_RGBA_08(rbuf[isrccol], gbuf[isrccol],
  145.             bbuf[isrccol], abuf[isrccol]);
  146.         else if (f->zsize == 3)
  147.             *ip = PACK_RGBA_08(rbuf[isrccol], gbuf[isrccol],
  148.             bbuf[isrccol], 0xff);
  149.         else
  150.             *ip = PACK_RGBA_08(rbuf[isrccol], rbuf[isrccol],
  151.             rbuf[isrccol], 0xff);
  152.         }
  153.  
  154.     } else {
  155.         /* 1 byte per pixel NORMAL image */
  156.         for (icol = 0, srccol = 0.5 * xsrcinc;
  157.             icol < ids->ixsize; icol++, srccol += xsrcinc, ip++) {
  158.         isrccol = (int) srccol;
  159.         if (f->zsize > 3)
  160.             *ip = PACK_RGBA_08(rbuf[isrccol], gbuf[isrccol],
  161.             bbuf[isrccol], abuf[isrccol]);
  162.         else if (f->zsize == 3)
  163.             *ip = PACK_RGBA_08(rbuf[isrccol], gbuf[isrccol],
  164.             bbuf[isrccol], 0xff);
  165.         else
  166.             *ip = PACK_RGBA_08(rbuf[isrccol], rbuf[isrccol],
  167.             rbuf[isrccol], 0xff);
  168.         }
  169.     }
  170.     }
  171.  
  172.     iclose(f);
  173.     return TRUE;
  174. }
  175.  
  176.  
  177. char *
  178. Info_SGI(struct iconDirStruct *ids, char *buf) {
  179.     int colormap;
  180.  
  181.     colormap = ids->subType >> 16;
  182.     sprintf(buf, "SGI format %s, %s, %d %s/pixel",
  183.     (colormap == CM_NORMAL) ?
  184.         ((ids->zsize >= 3) ?    "RGB image"        :
  185.                     "B/W image")       :
  186.     (colormap == CM_DITHERED) ? "3:3:2 image"      :
  187.     (colormap == CM_SCREEN)   ? "colorindex image" :
  188.     (colormap == CM_COLORMAP) ? "color map"        :
  189.                     "",
  190.     ((ids->subType & TYPEMASK) == 0) ?
  191.                     "Verbatim"         :
  192.                     "RLE",
  193.     (ids->subType & BPPMASK),
  194.     ((ids->subType & BPPMASK) == 1) ?
  195.                     "byte"             :
  196.                     "bytes"
  197.     );
  198.  
  199.     return buf;
  200. }
  201.  
  202. void
  203. Open_SGI(struct iconDirStruct *ids) {
  204.     char buf[PATH_MAX+64];
  205.     char *cmd;
  206.  
  207.     /* What to do on double-click of icon... */
  208.     if ((cmd = getenv("IBROWSE_SGI_OPEN_CMD")) != NULL)
  209.     /* Invoke the command in the environment variable. */
  210.     ;
  211.     
  212.     else if (useIconFiles)
  213.     /* Browsing from icon files.  Don't try to open an image file. */
  214.     return;
  215.  
  216.     else if (modKeys & SHIFTKEYBIT)
  217.     /* Shift-open, always ipaste */
  218.     sprintf(cmd = buf, "/usr/sbin/ipaste %s/%s", theDirName, ids->name);
  219.  
  220.     else if (modKeys & CTRLKEYBIT)
  221.     /* Ctrl-open, always scope */
  222.     sprintf(cmd = buf, "/usr/sbin/scope %s/%s", theDirName, ids->name);
  223.  
  224.     else
  225.     /* Default action - "ipaste" small images,
  226.      * "scope" images too large to fit comfortably on the screen.
  227.      */
  228.     sprintf(cmd = buf, "/usr/sbin/%s %s/%s",
  229.         (ids->xsize > getgdesc(GD_XPMAX) - IPASTE_MARGIN ||
  230.          ids->ysize > getgdesc(GD_YPMAX) - IPASTE_MARGIN) ?
  231.         "scope" : "ipaste",
  232.         theDirName, ids->name);
  233.  
  234.     system(cmd);
  235. }
  236.  
  237.  
  238. /* Low 16 slots of SGI default colormap */
  239. unsigned long lo16_SGI[] = {
  240.     0xff000000, 0xff0000ff, 0xff00ff00, 0xff00ffff,
  241.     0xffff0000, 0xffff00ff, 0xffffff00, 0xffffffff,
  242.     0xff555555, 0xff7171c6, 0xff71c671, 0xff388e8e,
  243.     0xffc67171, 0xff8e388e, 0xff8e8e38, 0xffaaaaaa
  244. };
  245.  
  246. void
  247. GetColormap_SGI() {
  248.     int i, r, g, b;
  249.  
  250.     myColormap_SGI = (unsigned long *) malloc(256 * sizeof(unsigned long));
  251.     /* Low 16 slots from a constant table */
  252.     for (i =  0; i <= 15; i++) myColormap_SGI[i] = lo16_SGI[i];
  253.     /* 16 through 31 are all black */
  254.     for (i = 16; i <= 31; i++) myColormap_SGI[i] = 0;
  255.     /* 32 through 55 are a blackish to whiteish ramp */
  256.     for (i = 32; i <= 55; i++) {
  257.     r = g = b = (i - 31) * 255 / (56 - 31);
  258.     myColormap_SGI[i] = PACK_RGBA_08(r, g, b, 0xff);
  259.     }
  260.     /* 56 through 255 are BRG 5x5x8 table */
  261.     for (i = 56; i <=255; i++) {
  262.     g = (i - 56) % 8;
  263.     r = (i - 56) / 8 % 5;
  264.     b = (i - 56) / 40;
  265.     myColormap_SGI[i] = PACK_RGBA_08(r*255/4, g*255/7, b*255/4, 0xff);
  266.     }
  267. }
  268.